/**
 * @file task_dispatcher.h
 * @author chengxiang (chengxiang@holomatic.com)
 * @brief
 * @version 0.1
 * @date 2023-04-14
 *
 * @copyright Copyright (C) 2023 HoloMatic Technology(Beijing) Co., Ltd. - All Rights Reserved.
 * Unauthorized copying of this file, via any medium is strictly prohibited,Proprietary and confidential.
 *
 */
#ifndef __SRC_TASK_DISPATCHER_H__
#define __SRC_TASK_DISPATCHER_H__

#include <atomic>
#include <memory>
#include <thread>

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

namespace dispatcher
{

class TaskDispatcherImpl;
class Thread;

/**
 * @brief class Task.
 */
class Task
{
public:
    /**
     * @brief Task running state.
     */
    enum State : uint8_t
    {
        Waiting,
        Running,
        Finished,
    };

    /**
     * @brief Task run once or lasting forever.
     */
    enum TaskType
    {
        Last,
        Once,
    };

public:
    virtual void Run() = 0;

    State GetState() const
    {
        return state_;
    }

    TaskType GetType() const
    {
        return type_;
    }

    bool Wait() const;

private:
    void SetState(State state)
    {
        state_ = state;
    }

    void SetTaskType(TaskType type)
    {
        type_ = type;
    }

private:
    std::atomic<State> state_;
    TaskType           type_;

    friend class TaskDispatcherImpl;
    friend class Thread;
};

/**
 * @brief class TaskDispatcher.
 */
class TaskDispatcher
{
public:
    using TaskSptr = std::shared_ptr<Task>;

public:
    explicit TaskDispatcher(uint32_t task_thread_n = 5u);

    void AddTask(TaskSptr task, Task::TaskType type = Task::Once);

private:
    std::shared_ptr<TaskDispatcherImpl> impl_sptr_;
};

}  // namespace dispatcher

#endif  // __SRC_TASK_DISPATCHER_H__
